package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"syscall"

	"golang.org/x/crypto/ssh"
	"golang.org/x/term"
)

func main() {
	// 命令行参数解析
	var (
		host     = flag.String("h", "", "SSH服务器地址")
		port     = flag.String("p", "22", "SSH端口号")
		username = flag.String("u", "", "SSH用户名")
	)
	flag.Parse()

	// 交互式输入缺失的参数
	if *host == "" {
		fmt.Print("请输入SSH服务器地址: ")
		fmt.Scanln(host)
	}
	if *username == "" {
		fmt.Print("请输入用户名: ")
		fmt.Scanln(username)
	}
	fmt.Print("请输入密码: ")
	password, _ := term.ReadPassword(int(syscall.Stdin))
	fmt.Println()

	// SSH客户端配置
	config := &ssh.ClientConfig{
		User: *username,
		Auth: []ssh.AuthMethod{
			ssh.Password(string(password)),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// 建立连接
	client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", *host, *port), config)
	if err != nil {
		log.Fatalf("无法连接到服务器: %v", err)
	}
	defer client.Close()

	// 创建会话
	session, err := client.NewSession()
	if err != nil {
		log.Fatalf("创建会话失败: %v", err)
	}
	defer session.Close()

	// 设置终端
	modes := ssh.TerminalModes{
		ssh.ECHO:          1,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}

	if err := session.RequestPty("xterm-256color", 80, 120, modes); err != nil {
		log.Fatalf("请求终端失败: %v", err)
	}

	// 设置输入输出
	session.Stdout = os.Stdout
	session.Stdin = os.Stdin
	session.Stderr = os.Stderr
	// 关键：显式启用TTY输入原始模式
	fd := int(os.Stdin.Fd())
	state, err := term.MakeRaw(fd)
	if err != nil {
		log.Fatalf("终端原始模式设置失败: %v", err)
	}
	defer term.Restore(fd, state) // [3][5]

	// 启动交互式shell
	if err := session.Shell(); err != nil {
		log.Fatalf("启动shell失败: %v", err)
	}

	// 等待会话结束
	if err := session.Wait(); err != nil {
		log.Fatalf("会话错误: %v", err)
	}
}
